/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Operations.Spatial;

import Global.Global;
import Operations.*;
import java.awt.image.BufferedImage;
import Operations.Geometry.Utilities;
/**
 *
 * @author littlechild
 */
public class OpSusan implements Operation{
    static int rgbmask=0xffffff;
    BufferedImage lastImage=null;
    BufferedImage blurredImage;
    public BufferedImage operate(BufferedImage image, double[] paras) {
        double t=paras[0];
        int squareR=(int)paras[1];
        IntTemplate templatex=new OpNeighbour().getSquareFilter(squareR);
        int maxN=0;
        for(int i=0;i!=templatex.template.length;++i) {
            for(int j=0;j!=templatex.template[0].length;++j) {
                if(templatex.template[i][j]!=0) {
                    maxN++;
                }
            }
        }
        double T=paras[2]*maxN; 
        //smooth the graph
        if(lastImage==null || !lastImage.equals(image))
            blurredImage=new OpNeighbour().operate(image,new double[]{Global.opGaussFiltering});
        //compute similarity 
        //&& Thresholding
        BufferedImage returnImage=new BufferedImage(image.getWidth(),image.getHeight(),image.getType());
        //starting the loop
        IntTemplate tmplt=(IntTemplate)templatex;
        int templateWidth=tmplt.template[0].length;
        int templateHeight=tmplt.template.length;
        int templateMiddlex=(templateWidth-1)/2;
        int templateMiddley=(templateHeight-1)/2;
        for (int i=0;i!=image.getWidth();++i) {
            for (int j=0;j!=image.getHeight();++j) {
                double c=0;
                int indexx;
                int indexy;
                for(int n=0;n!=templateWidth;++n) {
                    for (int m=0;m!=templateHeight;++m) {
                        indexx=i+n-templateMiddlex;
                        indexy=j+m-templateMiddley;
                        int grayDiff=OpNeighbour.getGray(Utilities.getFrom(blurredImage,i, j))
                                -OpNeighbour.getGray(Utilities.getFrom(blurredImage,indexx, indexy));
                        c+=Math.exp(-Math.pow(grayDiff/t,6));
                        //if(Math.abs(grayDiff)<t) 
                           // c++;
                    }
                }
                //if(Math.exp(-(c-t)*(c-t)/(2*sigma*sigma))>threshold) {
                if(c<T){
                    returnImage.setRGB(i, j,rgbmask);
                }
            }
        }
        return returnImage;
    }
}
